import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from matplotlib import font_manager

class DataAnalyzer:
    """数据分析类"""
    
    def __init__(self, data_path):
        """初始化数据分析器"""
        self.data_path = data_path
        self.data = None
        self.setup_chinese_font()
    
    def setup_chinese_font(self):
        """设置中文字体"""
        plt.rcParams['font.sans-serif'] = ['DengXian Bold', 'Microsoft YaHei UI Bold', 'SimHei']
        plt.rcParams['axes.unicode_minus'] = False
    
    def load_data(self):
        """加载数据"""
        self.data = pd.read_excel(self.data_path, header=1)  # 第二行作为列名
        print(f"✓ 数据加载完成，共{len(self.data)}行数据")
        return self
    
    def show_data_info(self):
        """显示数据基本信息"""
        print("\n" + "="*60)
        print("📊 数据基本信息")
        print("="*60)
        print(f"数据行数：{len(self.data)}")
        print(f"数据列数：{len(self.data.columns)}")
        
        print("\n📋 前10行数据：")
        print(self.data.head(10).to_string())
        
        print("\n📋 后15行数据：")
        print(self.data.tail(15).to_string())
        return self
    
    def clean_data(self):
        """清理数据"""
        print("\n" + "="*60)
        print("🧹 数据清理")
        print("="*60)
        
        # 统计原始数据情况
        null_count = self.data.isnull().sum().sum()
        duplicate_count = self.data.duplicated().sum()
        
        print(f"处理前缺失值数量：{null_count}")
        print(f"处理前重复数据数量：{duplicate_count}")
        
        # 处理缺失值和重复值
        self.data = self.data.fillna("无")
        self.data = self.data.drop_duplicates()
        
        print(f"✓ 缺失值已替换为'无'")
        print(f"✓ 重复数据已删除")
        print(f"处理后数据行数：{len(self.data)}")
        return self
    
    def get_employee_stats(self):
        """获取员工统计信息"""
        print("\n" + "="*60)
        print("👥 员工统计信息")
        print("="*60)
        
        # 在职员工统计
        active_employees = len(self.data[self.data['在职状态'] == '在职'])
        print(f"在职员工人数：{active_employees}人")
        
        # 工资统计
        salary_data = self.data[self.data['应发工资'].notna() & (self.data['应发工资'] != "无")]
        if not salary_data.empty:
            salary_values = self._parse_salary_column(salary_data['应发工资'])
            if not salary_values.empty:
                print(f"应发工资最大值：{salary_values.max():.2f}元")
                print(f"应发工资最小值：{salary_values.min():.2f}元")
                print(f"应发工资平均值：{salary_values.mean():.2f}元")
        return self
    
    def _parse_salary_column(self, salary_series):
        """解析工资列数据"""
        return pd.to_numeric(
            salary_series.astype(str).str.replace(',', '').str.replace(' ', ''), 
            errors='coerce'
        ).dropna()
    
    def add_new_employee(self):
        """添加新员工"""
        print("\n" + "="*60)
        print("➕ 添加新员工")
        print("="*60)
        
        new_employee = pd.DataFrame([{
            '序号': 993,
            '工号': 'GH993',
            '姓名': '李四',
            '性别': '女',
            '手机号': '13999999999',
            '出生年月': '19920315',
            '入职日期': '20240201',
            '年龄': 32,
            '在职状态': '在职',
            '工龄': 1,
            '籍贯': '上海市',
            '学历': '硕士',
            '基本工资': 7000,
            '应发工资': 9500
        }])
        
        self.data = pd.concat([self.data, new_employee], ignore_index=True)
        print("✓ 新员工李四(GH993)已添加")
        return self
    
    def update_employee_info(self, employee_id, field, new_value):
        """更新员工信息"""
        print(f"\n🔄 更新员工信息")
        mask = self.data['序号'] == employee_id
        if mask.any():
            self.data.loc[mask, field] = new_value
            print(f"✓ 序号{employee_id}的{field}已更新为{new_value}")
        else:
            print(f"❌ 未找到序号为{employee_id}的员工")
        return self
    
    def remove_employees(self, conditions):
        """删除满足条件的员工"""
        print("\n" + "="*60)
        print("🗑️ 删除员工记录")
        print("="*60)
        
        initial_count = len(self.data)
        condition_mask = conditions(self.data)
        self.data = self.data[~condition_mask]
        removed_count = initial_count - len(self.data)
        
        print(f"删除了{removed_count}条员工记录")
        return self
    
    def analyze_by_groups(self):
        """分组分析"""
        print("\n" + "="*60)
        print("📈 分组分析")
        print("="*60)
        
        try:
            valid_data = self.data[self.data['应发工资'].notna() & (self.data['应发工资'] != "无")].copy()
            valid_data['应发工资_数值'] = self._parse_salary_column(valid_data['应发工资'])
            
            # 按学历分组分析
            education_analysis = valid_data.groupby('学历')['应发工资_数值'].agg(['mean', 'count', 'std'])
            print("\n📚 不同学历员工工资分析：")
            print(education_analysis.round(2))
            
            # 按性别分组分析
            gender_analysis = valid_data.groupby('性别')['应发工资_数值'].agg(['mean', 'count', 'std'])
            print("\n👨‍👩‍👧‍👦 不同性别员工工资分析：")
            print(gender_analysis.round(2))
            
        except Exception as e:
            print(f"❌ 分组分析出现错误：{e}")
        
        return self
    
    def export_data(self, output_path='dataoutput.xlsx'):
        """导出数据"""
        print("\n" + "="*60)
        print("💾 导出数据")
        print("="*60)
        
        self.data.to_excel(output_path, index=False)
        print(f"✓ 数据已导出到{output_path}")
        return self

class PopulationVisualizer:
    """人口数据可视化类"""
    
    def __init__(self, data_path):
        self.data_path = data_path
        self.data = None
        self.setup_style()
    
    def setup_style(self):
        """设置绘图样式"""
        plt.style.use('seaborn-v0_8')
        plt.rcParams['font.sans-serif'] = ['DengXian Bold', 'Microsoft YaHei UI Bold', 'SimHei']
        plt.rcParams['axes.unicode_minus'] = False
        plt.rcParams['figure.figsize'] = (10, 6)
    
    def load_data(self):
        """加载人口数据"""
        self.data = pd.read_excel(self.data_path)
        print("✓ 人口数据加载完成")
        return self
    
    def plot_urban_rural_comparison(self):
        """绘制城乡人口对比柱状图"""
        fig, ax = plt.subplots(figsize=(14, 8))
        
        years = self.data['年份'].str.replace('年', '')
        x_pos = range(len(years))
        bar_width = 0.35
        
        bars1 = ax.bar([x - bar_width/2 for x in x_pos], self.data['城镇人口'], 
                      bar_width, label='城镇人口', color='#4CAF50', alpha=0.8)
        bars2 = ax.bar([x + bar_width/2 for x in x_pos], self.data['乡村人口'], 
                      bar_width, label='乡村人口', color='#FF9800', alpha=0.8)
        
        ax.set_xlabel('年份', fontsize=12)
        ax.set_ylabel('人口数量（万人）', fontsize=12)
        ax.set_title('2014-2022年城乡人口数据变化对比', fontsize=14, fontweight='bold')
        ax.set_xticks(x_pos)
        ax.set_xticklabels(years, rotation=45)
        ax.legend(fontsize=11)
        ax.grid(True, alpha=0.3)
        
        # 添加数值标签
        for bar in bars1:
            height = bar.get_height()
            ax.text(bar.get_x() + bar.get_width()/2., height + 100,
                   f'{int(height)}', ha='center', va='bottom', fontsize=9)
        
        plt.tight_layout()
        plt.savefig('城乡人口对比柱状图_v2.png', dpi=300, bbox_inches='tight')
        plt.show()
        return self
    
    def plot_gender_pie_chart(self):
        """绘制性别比例饼图"""
        data_2022 = self.data[self.data['年份'] == '2022年']
        if not data_2022.empty:
            male_pop = data_2022['男性人口'].iloc[0]
            female_pop = data_2022['女性人口'].iloc[0]
            
            fig, ax = plt.subplots(figsize=(10, 10))
            
            sizes = [male_pop, female_pop]
            labels = ['男性人口', '女性人口']
            colors = ['#2196F3', '#E91E63']
            explode = (0.05, 0.05)
            
            wedges, texts, autotexts = ax.pie(sizes, labels=labels, colors=colors,
                                            autopct='%1.2f%%', startangle=90,
                                            explode=explode, shadow=True)
            
            ax.set_title('2022年男女人口比例分布', fontsize=16, fontweight='bold', pad=20)
            
            # 美化文本
            for autotext in autotexts:
                autotext.set_color('white')
                autotext.set_fontsize(12)
                autotext.set_fontweight('bold')
            
            plt.savefig('2022年性别比例饼图_v2.png', dpi=300, bbox_inches='tight')
            plt.show()
        return self
    
    def plot_population_trend(self):
        """绘制人口变化趋势图"""
        fig, ax = plt.subplots(figsize=(12, 8))
        
        years = [int(year.replace('年', '')) for year in self.data['年份']]
        
        ax.plot(years, self.data['城镇人口'], marker='o', linewidth=3, 
                markersize=8, label='城镇人口', color='#4CAF50')
        ax.plot(years, self.data['乡村人口'], marker='s', linewidth=3, 
                markersize=8, label='乡村人口', color='#FF5722')
        
        ax.set_xlabel('年份', fontsize=12)
        ax.set_ylabel('人口数量（万人）', fontsize=12)
        ax.set_title('2014-2022年城镇与乡村人口变化趋势', fontsize=14, fontweight='bold')
        ax.legend(fontsize=12)
        ax.grid(True, alpha=0.3, linestyle='--')
        
        # 添加填充区域
        ax.fill_between(years, self.data['城镇人口'], alpha=0.3, color='#4CAF50')
        ax.fill_between(years, self.data['乡村人口'], alpha=0.3, color='#FF5722')
        
        plt.tight_layout()
        plt.savefig('人口变化趋势图_v2.png', dpi=300, bbox_inches='tight')
        plt.show()
        return self
    
    def plot_correlation_scatter(self):
        """绘制相关性散点图"""
        fig, ax = plt.subplots(figsize=(10, 8))
        
        # 创建散点图
        scatter = ax.scatter(self.data['年末总人口'], self.data['城镇人口'], 
                           c=range(len(self.data)), cmap='viridis', 
                           s=100, alpha=0.7, edgecolors='black', linewidth=1)
        
        # 添加趋势线
        z = np.polyfit(self.data['年末总人口'], self.data['城镇人口'], 1)
        p = np.poly1d(z)
        ax.plot(self.data['年末总人口'], p(self.data['年末总人口']), 
                "r--", alpha=0.8, linewidth=2)
        
        ax.set_xlabel('年末总人口（万人）', fontsize=12)
        ax.set_ylabel('城镇人口（万人）', fontsize=12)
        ax.set_title('城镇人口与年末总人口相关性分析', fontsize=14, fontweight='bold')
        ax.grid(True, alpha=0.3)
        
        # 添加颜色条
        cbar = plt.colorbar(scatter)
        cbar.set_label('年份顺序', fontsize=10)
        
        plt.tight_layout()
        plt.savefig('城镇人口相关性散点图_v2.png', dpi=300, bbox_inches='tight')
        plt.show()
        return self

def main():
    """主函数"""
    print("🚀 开始执行商务数据分析任务")
    
    # 任务一：数据分析
    print("\n" + "="*80)
    print("📊 任务一：pandas数据分析——公司人事财务数据分析")
    print("="*80)
    
    analyzer = DataAnalyzer('data.xlsx')
    analyzer.load_data() \
            .show_data_info() \
            .clean_data() \
            .get_employee_stats() \
            .add_new_employee() \
            .update_employee_info(990, '手机号', '15012345678') \
            .remove_employees(lambda df: (df['年龄'] > 55) & 
                                       (df['在职状态'] == '离职') & 
                                       (df['性别'] == '男')) \
            .analyze_by_groups() \
            .export_data()
    
    # 任务二：数据可视化
    print("\n" + "="*80)
    print("📈 任务二：Python可视化分析——人口数据可视化展示")
    print("="*80)
    
    visualizer = PopulationVisualizer('population.xlsx')
    visualizer.load_data() \
              .plot_urban_rural_comparison() \
              .plot_gender_pie_chart() \
              .plot_population_trend() \
              .plot_correlation_scatter()
    
    print("\n🎉 所有任务执行完成！")

if __name__ == "__main__":
    main() 